#include "CNDefMessageListener.h"

#include <ndefmessage.h>
#include <ndefrecord.h>

#include "NdefMessageObserver.h"
#include "NDefMessageHandle.h"
#include "XmlFactory.h"

#include "Log.h"

CNdefMessageListener * CNdefMessageListener::NewL(MNDefMessageObserver & aObserver)
    {
    CNdefMessageListener * self = NewLC(aObserver);
    CleanupStack::Pop(self);
    return self;
    }

CNdefMessageListener * CNdefMessageListener::NewLC(MNDefMessageObserver & aObserver)
    {
    CNdefMessageListener * self = new (ELeave) CNdefMessageListener(aObserver);
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
    }

CNdefMessageListener::~CNdefMessageListener()
    {
    delete iNdefDiscoveryExt;
    delete iNdefDiscovery;
    iNfcServer.Close();
    }

// -----------------------------------------------------------------------------
// CNdefMessageListener::StartNdefDiscovery
// -----------------------------------------------------------------------------
//
void CNdefMessageListener::StartNdefDiscoveryL(CNdefRecord::TNdefRecordTnf aTnf, TDesC8 const & aType)
    {
    User::LeaveIfError(iNdefDiscovery->AddNdefSubscription( aTnf, aType ));
    SetForegroundL(ETrue);
    LOG3(_L8("AddNdefSubscription( %d, %S ) successful!"), aTnf, &aType);
    }

void CNdefMessageListener::CancelDiscovery()
    {
    SetForegroundL(EFalse);
    iNdefDiscovery->RemoveAllNdefSubscription(); // TODO remove only one type?
    }

void CNdefMessageListener::SetForegroundL(TBool aOnForeground)
    {
    User::LeaveIfError(iNdefDiscoveryExt->SetToForeground(aOnForeground));
    }

void CNdefMessageListener::ConstructL()
    {
    iNfcServer.Open();
    iNdefDiscovery = CNdefDiscovery::NewL( iNfcServer );
    iNdefDiscovery->AddNdefMessageListener( *this );
    iNdefDiscoveryExt = CNdefDiscoveryExt::NewL(*iNdefDiscovery);
    }

// -----------------------------------------------------------------------------
// CNdefMessageListener::MessageDetected
// From MNdefMessageListener
// -----------------------------------------------------------------------------
//
void CNdefMessageListener::MessageDetected( CNdefMessage* aMessage )
    {
    LOG1(_L("MessageDetected!"));
    TRAP_IGNORE(HandleMessageL(aMessage));
    CancelDiscovery();
    }

void CNdefMessageListener::HandleMessageL( CNdefMessage* aMessage )
    {
    if( aMessage )
        {
        RNdefMessageHandle msg;
        msg.Open(aMessage);
        CleanupClosePushL(msg);
        iObserver.NDefMessageReceivedL(msg);
        CleanupStack::PopAndDestroy(&msg);
        }
    else
        {
        iObserver.NDefMessageReceptionFailedL();
        }
    }
